package com.hemaapp.yjnh.activity;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import xtom.frame.util.XtomToastUtil;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore.Video;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.hemaapp.hm_FrameWork.HemaNetTask;
import com.hemaapp.hm_FrameWork.result.HemaBaseResult;
import com.hemaapp.yjnh.BaseActivity;
import com.hemaapp.yjnh.R;
import com.hemaapp.yjnh.view.CameraPreview;

/**
 * 录制视频
 * */
public class CameraActivity extends BaseActivity {
	private Camera mCamera;
	private CameraPreview mPreview;

	private MediaRecorder mMediaRecorder;
	private Button captureButton;
	private Button okbutton;
	private Button cancelbutton;
	private TextView mRecordingTimeView; // 显示录制视频的时间
	private String recordTime; // 录制视频的长度,单位是s
	private ImageView mVideoFrame;

	private boolean isRecording = false;
	private long mRecordingStartTime;

	private int MAX_RECORDTIME = 8;
	private int ok_second; // 要显示的秒

	private String mCurrentVideoFilename;
	private Uri mCurrentVideoUri;

	private ContentValues mCurrentVideoValues;
	private ContentResolver mContentResolver;

	private static final String TAG = "TAG-CameraActivity";

	public static final int MEDIA_TYPE_IMAGE = 1;
	public static final int MEDIA_TYPE_VIDEO = 2;

	private static final int UPDATE_RECORD_TIME = 5;

	final int sdkVersion = Build.VERSION.SDK_INT;

	private final Handler mHandler = new MainHandler();

	private class MainHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case UPDATE_RECORD_TIME: {
				updateRecordingTime();
				break;
			}

			default:
				Log.v(TAG, "Unhandled message: " + msg.what);
				break;
			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏

		setContentView(R.layout.activity_camera);

		mContentResolver = getContentResolver();

		// Create an instance of Camera
		mCamera = getCameraInstance();
		if (mCamera == null)
			log_i("----------- mCamera is null------");

		// Create our Preview view and set it as the content of our activity.
		mPreview = new CameraPreview(mContext, mCamera);
		FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
		preview.addView(mPreview);

		mVideoFrame = (ImageView) findViewById(R.id.video_frame);

		mRecordingTimeView = (TextView) findViewById(R.id.timer);
		captureButton = (Button) findViewById(R.id.button_capture);
		okbutton = (Button) findViewById(R.id.button_ok);
		cancelbutton = (Button) findViewById(R.id.button_cancel);
		okbutton.setVisibility(View.INVISIBLE);
		cancelbutton.setVisibility(View.INVISIBLE);

		okbutton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (ok_second <= MAX_RECORDTIME)
					doReturnToCaller(true);
				else {
					XtomToastUtil.showShortToast(mContext, "时间过长,请重新录制");
				}
			}
		});

		cancelbutton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				doReturnToCaller(false);
			}
		});

		captureButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (isRecording) {
					stoprecode();
					showAlert();
				} else {
					// initialize video camera
					if (prepareVideoRecorder()) {
						// Camera is available and unlocked, MediaRecorder is
						// prepared,
						// now you can start recording
						mMediaRecorder.start();

						// inform the user that recording has started
						// setCaptureButtonText("Stop");
						captureButton.setText("停止");
						isRecording = true;
						mRecordingStartTime = SystemClock.uptimeMillis();
						updateRecordingTime();
					} else {
						// prepare didn't work, release the camera
						releaseMediaRecorder();
						// inform user
					}
				}
			}
		});
	}

	@Override
	protected boolean onKeyBack() {
		return false;
	}

	@Override
	protected boolean onKeyMenu() {
		return false;
	}

	@Override
	protected void findView() {

	}

	@Override
	protected void getExras() {

	}

	@Override
	protected void setListener() {

	}

	public void stoprecode() {
		// stop recording and release camera
		mMediaRecorder.stop(); // stop the recording
		releaseMediaRecorder(); // release the MediaRecorder object
		mCamera.lock(); // take camera access back from MediaRecorder

		// inform the user that recording has stopped
		// setCaptureButtonText("Capture");
		captureButton.setText("开始");
		isRecording = false;

		registerVideo();

		okbutton.setVisibility(View.VISIBLE);
		cancelbutton.setVisibility(View.VISIBLE);
		captureButton.setVisibility(View.INVISIBLE);
	}

	/** A safe way to get an instance of the Camera object. */
	public static Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open(); // attempt to get a Camera instance
		} catch (Exception e) {
			// Camera is not available (in use or does not exist)
		}
		
//		if (c != null) {// 设置录像为竖屏
//		Parameters params = c.getParameters();
//		params.set("orientation", "portrait");
//		c.setParameters(params);
//	}
		return c; // returns null if camera is unavailable
	}

	private boolean prepareVideoRecorder() {
		mMediaRecorder = new MediaRecorder();// 创建mediarecorder对象
		// stop preview before making changes

		try {
			mCamera.stopPreview();
		} catch (Exception e) {
			// ignore: tried to stop a non-existent preview
		}

		mCamera.unlock();
		mMediaRecorder.setCamera(mCamera);

		// 设置录制视频源为Camera(相机)
		mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
		mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

		set_QUALITY();
		// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4
		// mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

		// mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
		// mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
		// mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
		// mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
		// mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));

		// 设置视频文件输出的路径
		// mCurrentVideoFilename =
		// getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(); //newFileName();
		createVideoPath();
		mMediaRecorder.setOutputFile(mCurrentVideoFilename);

		mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

		mMediaRecorder.setMaxFileSize(5 * 1024 * 1024);
		mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
			public void onInfo(MediaRecorder mr, int what, int extra) {
				if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
					if (mMediaRecorder != null) {
						// mMediaRecorder.stop();
						// mMediaRecorder.release();
						// mMediaRecorder=null;

						stoprecode();
						showAlert();
					}
				}

			}
		});

		try {
			// 准备录制
			mMediaRecorder.prepare();
			// 开始录制
			// mMediaRecorder.start();
		} catch (IllegalStateException e) {
			Log.d(TAG,
					"IllegalStateException preparing MediaRecorder: "
							+ e.getMessage());
			releaseMediaRecorder();

			return false;
		} catch (IOException e) {
			Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
			releaseMediaRecorder();

			return false;
		}
		return true;
	}

	@TargetApi(15)
	public void set_QUALITY() {
		boolean hasqvga = false, has480p = false, hasCIF = false, hasQCIF = false;
		if (sdkVersion >= 15) {
			hasqvga = CamcorderProfile
					.hasProfile(CamcorderProfile.QUALITY_QVGA);
		}
		if (sdkVersion >= 11) {
			has480p = CamcorderProfile
					.hasProfile(CamcorderProfile.QUALITY_480P);
			hasCIF = CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_CIF);
			hasQCIF = CamcorderProfile
					.hasProfile(CamcorderProfile.QUALITY_QCIF);
		}

		if (hasqvga) {
			Log.d(TAG, "CamcorderProfile.QUALITY_QVGA");
			mMediaRecorder.setProfile(CamcorderProfile
					.get(CamcorderProfile.QUALITY_QVGA));
		} else if (has480p) {
			Log.d(TAG, "CamcorderProfile.QUALITY_480P");
			mMediaRecorder.setProfile(CamcorderProfile
					.get(CamcorderProfile.QUALITY_480P));
		} else if (hasCIF) {
			Log.d(TAG, "CamcorderProfile.QUALITY_CIF");
			mMediaRecorder.setProfile(CamcorderProfile
					.get(CamcorderProfile.QUALITY_CIF));
		} else if (hasQCIF) {
			Log.d(TAG, "CamcorderProfile.QUALITY_QCIF");
			mMediaRecorder.setProfile(CamcorderProfile
					.get(CamcorderProfile.QUALITY_QCIF));
		} else {
			Log.d(TAG, "CamcorderProfile.QUALITY_LOW");
			mMediaRecorder.setProfile(CamcorderProfile
					.get(CamcorderProfile.QUALITY_LOW));
		}
	}

	public String newFileName() {
		try {
			return File.createTempFile("/mov_", ".3gp").getAbsolutePath();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	// public void setCaptureButtonText(String txt) {
	// captureButton.setText(txt);
	// }

	@Override
	protected void onPause() {
		super.onPause();
		releaseMediaRecorder(); // if you are using MediaRecorder, release it
								// first
		releaseCamera(); // release the camera immediately on pause event
	}

	private void releaseMediaRecorder() {
		if (mMediaRecorder != null) {
			mMediaRecorder.reset(); // clear recorder configuration
			mMediaRecorder.release(); // release the recorder object
			mMediaRecorder = null;
			mCamera.lock(); // lock camera for later use
		}
	}

	private void releaseCamera() {
		if (mCamera != null) {
			mCamera.release(); // release the camera for other applications
			mCamera = null;
		}
	}

	/** Create a File for saving an image or video */
	// private static File getOutputMediaFile(int type){
	// // To be safe, you should check that the SDCard is mounted
	// // using Environment.getExternalStorageState() before doing this.
	//
	// File mediaStorageDir = new
	// File(Environment.getExternalStoragePublicDirectory(
	// Environment.DIRECTORY_PICTURES), "MyCameraApp");
	// // This location works best if you want the created images to be shared
	// // between applications and persist after your app has been uninstalled.
	//
	// // Create the storage directory if it does not exist
	// if (! mediaStorageDir.exists()){
	// if (! mediaStorageDir.mkdirs()){
	// Log.d("MyCameraApp", "failed to create directory");
	// return null;
	// }
	// }
	//
	// // Create a media file name
	// String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
	// Date());
	// File mediaFile;
	// if (type == MEDIA_TYPE_IMAGE){
	// mediaFile = new File(mediaStorageDir.getPath() + File.separator +
	// "IMG_"+ timeStamp + ".jpg");
	// } else if(type == MEDIA_TYPE_VIDEO) {
	// mediaFile = new File(mediaStorageDir.getPath() + File.separator +
	// "VID_"+ timeStamp + ".mp4");
	// } else {
	// return null;
	// }
	//
	// return mediaFile;
	// }

	private void updateRecordingTime() {
		if (!isRecording) {
			return;
		}
		long now = SystemClock.uptimeMillis();
		long delta = now - mRecordingStartTime;

		long next_update_delay = 1000 - (delta % 1000);
		long seconds;

		seconds = delta / 1000; // round to nearest

		ok_second = Integer.valueOf(String.valueOf(seconds));

		long minutes = seconds / 60;
		long hours = minutes / 60;
		long remainderMinutes = minutes - (hours * 60);
		// long remainderSeconds = seconds - (minutes * 60);

		// String secondsString = Long.toString(remainderSeconds);
		int remainSec = MAX_RECORDTIME - ok_second;
		String secondsString = String.valueOf(remainSec);
		if (secondsString.length() < 2) {
			secondsString = "0" + secondsString;
		}
		String minutesString = Long.toString(remainderMinutes);
		if (minutesString.length() < 2) {
			minutesString = "0" + minutesString;
		}
		String text = minutesString + ":" + secondsString;
		if (hours > 0) {
			String hoursString = Long.toString(hours);
			if (hoursString.length() < 2) {
				hoursString = "0" + hoursString;
			}
			text = hoursString + ":" + text;
		}
		recordTime = String.valueOf(seconds);

		if (remainSec == 0) {
			mRecordingTimeView.setText("00:" + MAX_RECORDTIME);
			stoprecode();
			showAlert();
		} else {
			mRecordingTimeView.setText(text);
			mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME,
					next_update_delay);
		}

	}

	private String createName(long dateTaken) {
		Date date = new Date(dateTaken);
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				getString(R.string.video_file_name_format));

		return dateFormat.format(date);
	}

	/**
	 * 判断是否有外部存储
	 * 
	 * @return 如果有返回true，否则false
	 */
	public static final boolean isExternalMemoryAvailable() {
		return Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState());
	}

	/**
	 * 获取临时文件存放目录
	 * 
	 * @param context
	 * @return
	 */
	public static final String getTempFileDir(Context context) {
		String path = isExternalMemoryAvailable() ? context
				.getExternalFilesDir(null).getPath() + "/temp/" : context
				.getFilesDir().getPath() + "/temp/";
		File file = new File(path);
		if (!file.exists())
			file.mkdirs();
		return path;
	}

	private void createVideoPath() {
		long dateTaken = System.currentTimeMillis();
		String title = createName(dateTaken);
		String filename = title + ".3gp";

		String cameraDirPath = getTempFileDir(this);
		String filePath = cameraDirPath + "/" + filename;

		ContentValues values = new ContentValues(7);
		values.put(Video.Media.TITLE, title);
		values.put(Video.Media.DISPLAY_NAME, filename);
		values.put(Video.Media.DATE_TAKEN, dateTaken);
		values.put(Video.Media.MIME_TYPE, "video/3gpp");
		values.put(Video.Media.DATA, filePath);

		mCurrentVideoFilename = filePath;
		Log.v(TAG, "Current camera video filename: " + mCurrentVideoFilename);

		mCurrentVideoValues = values;
	}

	private void registerVideo() {
		Uri videoTable = Uri.parse("content://media/external/video/media");
		mCurrentVideoValues.put(Video.Media.SIZE, new File(
				mCurrentVideoFilename).length());
		try {
			mCurrentVideoUri = mContentResolver.insert(videoTable,
					mCurrentVideoValues);
		} catch (Exception e) {
			// We failed to insert into the database. This can happen if
			// the SD card is unmounted.
			mCurrentVideoUri = null;
			mCurrentVideoFilename = null;
		} finally {
			Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
		}
	}

	private void showAlert() {
		if (mCurrentVideoFilename != null) {
			Bitmap src = ThumbnailUtils.createVideoThumbnail(
					mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);

			mVideoFrame.setImageBitmap(src);
			mVideoFrame.setVisibility(View.VISIBLE);
		}
	}

	private void doReturnToCaller(boolean valid) {
		int resultCode;
		if (valid) {
			resultCode = RESULT_OK;
			mIntent.setData(mCurrentVideoUri);
			mIntent.putExtra("recordTime", recordTime);
		} else {
			resultCode = RESULT_CANCELED;
		}
		setResult(resultCode, mIntent);
		finish();
	}

	@Override
	protected void callBeforeDataBack(HemaNetTask netTask) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void callAfterDataBack(HemaNetTask netTask) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void callBackForServerSuccess(HemaNetTask netTask,
			HemaBaseResult baseResult) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void callBackForServerFailed(HemaNetTask netTask,
			HemaBaseResult baseResult) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void callBackForGetDataFailed(HemaNetTask netTask, int failedType) {
		// TODO Auto-generated method stub

	}

}
